local blaze = require "blaze"
local game = require "club.threecard.hbsl"

local log = game.logging.get("gameplay")

local M = {}

local timer = nil

M.throttleable = true

M.state = {
    phase_id = 0,
    countdown = 0,
    left_count = 0, -- 当前红包剩余可抢的次数
    last_sender_id = -1,
    players = {},
    red_packets = {}, -- 所有红包缓存， 按发送顺序

    scene = nil,

    selected_no = nil, -- 当前选中需要发的雷号
    grab_request_sent = false, -- 当前是否已经发送了抢红包的请求
}

M.getters = {
    selected_amount = function(state)
        return game.store.bet_amounts.state.amount
    end
}

M.actions = {
    find_player_by_id = function(store, state, id)
        return state.players[id]
    end
}

M.mutations = {
    set_no = function(store, state, no)
        state.selected_no = no
    end,

    send_packet = function(store, state, args)
        local player = blaze.kbe.player()
        if not player then
            return
        end
        local amount = state.selected_amount
        local no = state.selected_no or math.floor(math.random(0, 9))
        player:send(amount, no)
    end,

    grab_packet = function(store, state, args)
        if state.grab_request_sent then
            return false
        end
        if state.left_count <= 0 then
            return false
        end
        local player = game.kbe.player()
        if not player then
            return false
        end
        player:grab()
        state.grab_request_sent = true
        return true
    end,

    on_player_enter = function(store, state, player)
        -- TODO:使用单独的模块统一管理player
        state.players[player.id] = player
        store.emit("玩家进场")
    end,

    on_player_leave = function(store, state, player)
        -- TODO:使用单独的模块统一管理player
        state.players[player.id] = nil
        store.emit("玩家离场")
    end,

    set_phase = function(store, state, args)
        state.phase_id = args.phase_id
        state.countdown = math.floor(args.countdown / 1000)

        if timer then
            game.coroutine.stop(timer)
        end

        if state.countdown > 0 then
            timer = game.coroutine.start(function()
                while state.countdown > 0 do
                    game.coroutine.wait(1)
                    state.countdown = state.countdown - 1
                    store.emit("countdown变更")
                end
            end)
        end

        store.emit("阶段变更")
    end,

    on_red_packet_appeared = function(store, state, args)
        state.grab_request_sent = false

        local sender_id = args.sender_id
        local amount = args.amount
        local size = args.size
        local no = args.no

        state.left_count = size

        if state.red_packets[1] and state.red_packets[1].sender_id == sender_id then
            table.remove(state.red_packets, 1)
        else
            if #state.red_packets == 0 then
                log.warn("当前红包缓存是空的")
            else
                log.warn("红包没有按照队列顺序发？")
                log.debug(game.dump(state.red_packets))
                log.debug(sender_id)
            end
        end

        local player = store.find_player_by_id(sender_id)
        if not player then
            log.warn("发完红包就跑了？sender_id:"..sender_id)
            return
        end

        state.last_sender_id = sender_id
        state.last_red_packet_args = {player = player, amount = amount, count = size, no = no}
        store.emit("红包现世", state.last_red_packet_args)
        store.emit("红包队列变化")
    end,

    on_reveal = function(store, state, args)
        local sender_id = args.sender_id
        local no = args.n
        local win = args.win
        local hits = args.hits
        local records = {}
        local max_amount = -1
        for _, t in ipairs(args.records) do
            table.insert(records, {player_id = t[1], amount = t[2]})
            if max_amount < t[2] then
                max_amount = t[2]
            end
        end
        local player = store.find_player_by_id(sender_id)
        store.emit("红包结果", {player = player, no = no, win = win, hits = hits, records = records, max_amount = max_amount})
    end,

    on_settle = function(store, state, args)
        store.emit("结算", args)
    end,

    on_grab = function(store, state, player)
        state.left_count = state.left_count - 1
        store.emit("红包变更", state.last_red_packet_args)
        store.emit("抢红包", player)
    end,

    on_self_grab = function(store, state, amount)
        store.emit("自己抢到红包", amount)
    end,

    on_send = function(store, state, args)
        local player = args.player
        local amount = args.amount
        local count = args.count

        for _, packet in ipairs(state.red_packets) do
            if packet.sender_id == player.id then
                log.warn("红包已经存在？ sender_id:"..packet.sender_id)
                return
            end
        end

        table.insert(state.red_packets, {sender_id = player.id, amount = amount, count = count})

        store.emit("红包队列变化")
    end,

    on_game_init = function(store, state, scene)
        state.scene = scene
        store.emit("恢复游戏场景")

        state.red_packets = {}
        if scene.red_packet ~= -1 then
            table.insert(state.red_packets, { sender_id = scene.red_packet.sender_id, amount = scene.red_packet.amount, count = scene.red_packet.size })
            store.on_red_packet_appeared(scene.red_packet)
            for _, record in ipairs(scene.red_packet.records) do
                local player = state.players[record[1]]
                if player then
                    store.on_grab(player)
                end
            end
        end

        for _, packet in ipairs(scene.packet_queue) do
            table.insert(state.red_packets, {sender_id = packet.sender_id, amount = packet.amount, count = packet.size})
        end

        game.store.gameplay.set_phase({phase_id = scene.phase_id, countdown = scene.left_time * 1000})
        store.emit("红包队列变化")
    end
}

return M